﻿using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using Microsoft.Practices.Unity;
using Might.GraphicsEditor.Presenter;
using Might.GraphicsEditor.Tools;
using Might.Infrastructure.Annotations.Graphics;
using Might.Infrastructure.View;

namespace Might.GraphicsEditor {
    /// <summary>
    /// Class responsible for graphic editing of Icons and Models
    /// </summary>
    public partial class IconEditor : ITabEditor {
        /// <summary>
        /// static property used for saving which instance of drawcanvas is currently active
        /// </summary>
        public static IconEditor SelectedCanvas;

        internal IGraphicsAnnotation ga;
        internal IUnityContainer container;

        internal IconPresenter presenter;

        internal ITool currentTool;
        internal Rubberband rubberbandTool;
        internal EllipseTool ellipseTool;
        internal RectangleTool rectangleTool;

        internal Resizer resizer { get; set; }

        /// <summary>
        /// Public default constructor for class DrawCanvas.
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="ga">Graphic Annotation to be used in this canvas.</param>
        public IconEditor(IUnityContainer container, IGraphicsAnnotation ga) {
            InitializeComponent();
            this.container = container;
            //container.Resolve<IMightLogger>().Log( this, "Draw canvas init" );      
            this.ga = ga;

            presenter = new IconPresenter(ga) {
                VerticalAlignment = VerticalAlignment.Center, 
                HorizontalAlignment = HorizontalAlignment.Center
            };

            ContentViewer.Children.Insert(1, presenter);

            // top layer for resizer adorner and other technical stuff
            resizer = new Resizer(presenter);
            adorner.Children.Add(resizer);
            adorner.Children.Add(new RadiusRod(presenter));

            rubberbandTool = new Rubberband(presenter);
            ellipseTool = new EllipseTool(presenter);
            rectangleTool = new RectangleTool(presenter);
            currentTool = rubberbandTool;
            adorner.Children.Add(rubberbandTool);

            SelectedCanvas = this;

            SizeChanged += IconEditor_SizeChanged;

            // temp, test of Bitmaps
            //IGraphicsBitmap gp = ga[0].CreatePrimitive(typeof(IGraphicsBitmap)) as IGraphicsBitmap;
            //gp.Image = new BitmapImage(new Uri("/img1.jpg", UriKind.Relative));
            //gp.Width = gp.Height = 125;
            //gp.Top = gp.Left = 50;
            //canvas.Children.Add(new LeafBitmap(gp));
            //ga[0].AddPrimitive(gp);
        }

        void IconEditor_SizeChanged(object sender, SizeChangedEventArgs e) {
            clipGeometry.Rect = new Rect(0, 0, e.NewSize.Width, e.NewSize.Height);
        }

        #region ITabEditor Members

        /// <summary>
        /// This function ought to be called every time, when the active iconeditor is changed.
        /// </summary>
        public void TabSelected() {
            SelectedCanvas = this;
            SelectedCanvas.resizer.graphics_SelectionChanged(this, null);
        }

        #endregion

        #region Mouse handlers

        /// <summary>
        /// Event handler for Left Button clicks on canvas surface.
        /// </summary>
        /// <param name="sender">canvas</param>
        /// <param name="e">mouse parameters</param>
        protected void DrawCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
            if (currentTool != null) {
                currentTool.GetMouseLeftButtonDown(sender, e);
                currentTool = rubberbandTool;
            }
        }

        /// <summary>
        /// Event handler for Mouse moves on canvas surface.
        /// </summary>
        /// <param name="sender">canvas</param>
        /// <param name="e">mouse parameters</param>
        protected void DrawCanvas_MouseMove(object sender, MouseEventArgs e) {
            if (currentTool != null) {
                currentTool.GetMouseMove(sender, e);
            }
        }

        /// <summary>
        /// Event handler for Left Button release event on canvas surface.
        /// </summary>
        /// <param name="sender">canvas</param>
        /// <param name="e">mouse paramteres</param>
        protected void DrawCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) {
            if (currentTool != null) {
                currentTool.GetMouseLeftButtonUp(sender, e);
                e.Handled = true;
            }
        }

        #endregion

        #region Keyboard handlers

        /// <summary>
        /// Unified input for key pressed in GraphicsEditor.
        /// </summary>
        /// <param name="sender">Sender of current key input.</param>
        /// <param name="e">Pressed key.</param>
        private void DrawCanvas_KeyDown(object sender, KeyEventArgs e) {
            switch (e.Key) {
                case Key.Delete:
                    presenter.DeleteSelection();
                    break;
                default:
                    break;
            }
        }

        #endregion

        #region Button handlers

        // should be replaced with commands or similar logic

        private void Select_Click(object sender, RoutedEventArgs e) {
            currentTool = rubberbandTool;
        }

        private void Ellipse_Click(object sender, RoutedEventArgs e) {
            currentTool = ellipseTool;
        }

        private void Rectangle_Click(object sender, RoutedEventArgs e) {
            currentTool = rectangleTool;
        }

        private void Delete_Click(object sender, RoutedEventArgs e) {
            presenter.DeleteSelection();
        }

        private void Up_Click(object sender, RoutedEventArgs e) {
            presenter.UpSelection();
        }

        private void Down_Click(object sender, RoutedEventArgs e) {
            presenter.DownSelection();
        }

        private void Top_Click(object sender, RoutedEventArgs e) {
            presenter.TopSelection();
        }

        private void Bottom_Click(object sender, RoutedEventArgs e) {
            presenter.BottomSelection();
        }

        #endregion

        #region Zoom Slider handlers

        private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) {
            if (ZoomSlider != null &&
                ZoomSlider.Value >= 0.5 && ZoomSlider.Value <= 2) {
                // TODO create binding
                ContentScale.ScaleX = ContentScale.ScaleY = ZoomSlider.Value;
            }
        }

        #endregion
    }
}
